#pragma once
#include <string>
#include <vector>
#include <assert.h>

#include "point.h"
#include "string_utils.h"


struct StringDouble {
    int32_t int_part;
    std::string frac_part;

    StringDouble() : int_part(0), frac_part("0") {}
    StringDouble(const std::string& value)
    {
        std::vector<std::string> splits = SplitString(value, '.');
        assert(splits.size() <= 2);

        int_part = std::stoi(splits[0]);
        if (splits.size() == 2) {
            frac_part = splits[1];
        } else {
            frac_part = "0";
        }
    }

    double ToDouble() const
    {
        return std::stod(ToString());
    }

    std::string ToString() const
    {
        return std::to_string(int_part) +  std::string(".") + frac_part;
    }
};


struct String3DPoint {
    StringDouble x, y, z;

    String3DPoint(const std::string& string) : x("0.0"), y("0.0"), z("0.0")
    {
        std::vector<std::string> splits = SplitString(string, ',');
        assert(splits.size() == 3 || splits.size() == 2);

        x = StringDouble(splits[0]);
        y = StringDouble(splits[1]);
        if (splits.size() == 3) {
            z = StringDouble(splits[2]);
        }
    }

    String3DPoint(const BaseGeo::Point point) :
        x(std::to_string(point.x)),
        y(std::to_string(point.y)),
        z(std::to_string(point.z))
    {}

    BaseGeo::Point ToDoublePoint() const
    {
        return BaseGeo::Point(
            x.ToDouble(),
            y.ToDouble(),
            z.ToDouble()
        );
    }
};